/**
 *
 */
package cn.touna.jss.modules.third.zhima.service;

import cn.touna.risk.api.enums.SystemErrorCodeEnum;
import cn.touna.jss.common.factory.ResponseFactory;
import cn.touna.jss.modules.adapter.ApiMapping;
import cn.touna.jss.modules.third.zhima.client.GetAuthWatchlistGetClient;
import cn.touna.jss.modules.third.zhima.client.PCH5PageAuthClient;
import cn.touna.jss.modules.third.zhima.client.ScoreGetClient;
import cn.touna.jss.modules.third.zhima.client.ZmDataFeedbackClient;
import cn.touna.jss.modules.third.zhima.entity.*;
import cn.touna.risk.api.domain.Response;
import com.alibaba.fastjson.JSON;
import com.antgroup.zmxy.openplatform.api.response.ZhimaAuthInfoAuthqueryResponse;
import com.antgroup.zmxy.openplatform.api.response.ZhimaCreditScoreGetResponse;
import com.google.common.base.Strings;
import org.apache.commons.lang3.StringUtils;
import org.apache.logging.log4j.LogManager;
import org.apache.logging.log4j.Logger;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.util.CollectionUtils;

import java.net.URLDecoder;
import java.util.Date;
import java.util.Map;

/**
 * <p>
 * 芝麻接口服务
 * </P>
 *
 * @author tianhuaxing 2017年5月19日 下午5:41:25
 * @since 1.0.0.000
 */
@Service
public class ZhimaService {

    private static final Logger logger = LogManager.getLogger(ZhimaService.class);

    @Autowired
    private GetAuthWatchlistGetClient getAuthWatchlistGetClient;

    @Autowired
    private PCH5PageAuthClient pCH5PageAuthClient;

    @Autowired
    private ScoreGetClient scoreGetClient;

    @Autowired
    private ZmDataFeedbackClient zmDataFeedbackClient;

    /**
     * 授权查询
     *
     * @param
     * @return
     */
//    @ApiMapping("Zhima.accreditQuery")
    public Response accreditQuery(AccreditDto accreditDto) {
        logger.info("REQ【芝麻授权查询】传入参数paramStr:{}", accreditDto);
        Response response = new Response();
        AccreditQueryResultDto resultDto = new AccreditQueryResultDto();
        try {
            //判断查询条件不能全部为空
            if (checkQueryParam(accreditDto)) {
                resultDto = resultDto.server_param_limit(resultDto, accreditDto.getSid());
                return response.fail(SystemErrorCodeEnum.JSS_PARAM_CHECK_FAILED, resultDto);
            }
            // 1.首先查询用户是否授权
            ZhimaAuthInfoAuthqueryResponse result = getAuthWatchlistGetClient.zhimaAuthInfoReq(accreditDto);
            if (result == null) {
                logger.info("【芝麻授权查询】结束，查询芝麻授权返回对象为空...");
                resultDto = resultDto.server_error(resultDto, accreditDto.getSid());
                return response.fail(SystemErrorCodeEnum.JSS_CALL_EXTSYSTEM_ERROR, resultDto);
            }
            Boolean success = result.isSuccess();
            Boolean authorized = result.getAuthorized();
            resultDto.setSuccess(String.valueOf(success));
            resultDto.setRetCode(result.getErrorCode());
            resultDto.setRetMessage(URLDecoder.decode(String.valueOf(result.getErrorMessage()), "UTF-8"));
            if (success && authorized) {
                // 如果授权直接返回成功，并查询芝麻评分
                String openId = result.getOpenId();
                ZhimaCreditScoreGetResponse zhimaScore = scoreGetClient.zhimaCreditWatchlistGet(openId, accreditDto.getSid());
                if (zhimaScore != null && zhimaScore.isSuccess() == true) {
                    AccreditQueryData data = new AccreditQueryData();
                    data.setScore(zhimaScore.getZmScore());
                    data.setCreateTime(new Date());
                    resultDto.setRetData(data);
                }
                resultDto = resultDto.server_accredi_success(resultDto);
            } else {
                resultDto = resultDto.server_accredi_fail(resultDto, accreditDto.getSid());
                response = ResponseFactory.fail(SystemErrorCodeEnum.JSS_EXTSYSTEM_RESP_ERROR,resultDto.getRetCode() + ":" + resultDto.getRetMessage());
                response.setData(resultDto);
                return response;
            }
        } catch (Exception e) {
            logger.error("【芝麻授权查询】芝麻授权查询接口出错,errMsg:{}", e.getMessage());
            resultDto = resultDto.server_error(resultDto, accreditDto.getSid());
            response = ResponseFactory.fail(SystemErrorCodeEnum.JSS_CALL_EXTSYSTEM_ERROR, e.getMessage());
            response.setData(resultDto);
            return response;
        }
        logger.info("【芝麻授权查询】结束!返回信息,result:{}", JSON.toJSON(resultDto));
        return response.success(resultDto);
    }

    /**
     * 芝麻授权
     *
     * @param accreditDto
     * @return
     */
//    @ApiMapping("Zhima.accredit")
    public Response accredit(AccreditDto accreditDto) {
        logger.info("【芝麻授权】开始，请求参数：[{}]", accreditDto);
        Response response = new Response();
        AccreditResultDto resultDto = new AccreditResultDto();
        try {
            //判断查询条件不能全部为空
            if (checkQueryParam(accreditDto)) {
                resultDto = resultDto.server_param_limit(resultDto, accreditDto.getSid());
                return response.fail(SystemErrorCodeEnum.JSS_PARAM_CHECK_FAILED, resultDto);
            }
            String url = pCH5PageAuthClient.generatePcPageAuthUrl(accreditDto);
            AccreditData data = new AccreditData();
            data.setSid(accreditDto.getSid());
            data.setUrl(url);
            resultDto.setRetData(data);
            resultDto = resultDto.server_accrediting(resultDto);
        } catch (Exception e) {
            logger.error("【芝麻授权】芝麻授权接口出错,sid:{},errMsg:{}", accreditDto.getSid(), e.getMessage());
            resultDto = resultDto.server_error(resultDto, accreditDto.getSid());
            return response.fail(SystemErrorCodeEnum.JSS_EXTSYSTEM_RESP_ERROR, resultDto);
        }
        logger.info("【芝麻授权】结束!返回信息{}", JSON.toJSON(resultDto));
        return response.success(resultDto);
    }

    private Response accreditCallback(AccreditCallbackDto accreditCallbackDto) {
        logger.info("【芝麻授权回调】开始，params：{}", accreditCallbackDto);
        Response response = new Response();
        AccreditCallbackResultDto resultDto = new AccreditCallbackResultDto();
        AccreditCallbackData data = new AccreditCallbackData();
        try {
            Map<String, String> map = pCH5PageAuthClient.parseFromReturnUrl(accreditCallbackDto);
            if (CollectionUtils.isEmpty(map)) {
                logger.info("【芝麻授权回调】结束，解密对象为空...");
                resultDto = resultDto.server_error(resultDto, accreditCallbackDto.getSid());
                return response.fail(SystemErrorCodeEnum.JSS_EXTSYSTEM_RESP_ERROR, resultDto);
            }
            String openId = map.get("open_id");
            String success = map.get("success");
            String stateJson = map.get("state");
            AccreditDto accredit = new AccreditDto();
            if (StringUtils.isNotBlank(stateJson)) {
                stateJson = URLDecoder.decode(stateJson, "UTF-8");
                Map<String, String> mapState = (Map<String, String>) JSON.parse(stateJson);
                if (mapState != null) {
                    accredit.setName(mapState.get("name"));
                    accredit.setIdCard(mapState.get("idCard"));
                    accredit.setState(mapState.get("url"));
                    accredit.setUserId(mapState.get("userId"));
                    accredit.setBusinessId(mapState.get("businessId"));
                }
            }
            String retCode = map.get("error_code");
            String retMessage = map.get("error_message") + "";
            data.setUrl(accredit.getState());
            data.setSid(accreditCallbackDto.getSid());
            resultDto.setRetCode(retCode);
            resultDto.setRetMessage(URLDecoder.decode(retMessage, "UTF-8"));
            resultDto.setSuccess(success);
            resultDto.setRetData(data);
            if ("true".equals(success)) {
                // 调用芝麻分数
                try {
                    ZhimaCreditScoreGetResponse zhimaScore = scoreGetClient.zhimaCreditWatchlistGet(openId, accreditCallbackDto.getSid());
                    if (zhimaScore != null && zhimaScore.isSuccess()) {
                        try {
                            // TODO存储返回分数
                        } catch (Exception e) {
                            logger.error("【认证中心-芝麻分】存储数据出错,sid:{},errMsg:{}", accreditCallbackDto.getSid(), e.getMessage());
                        }
                    }
                } catch (Exception e) {
                    logger.error("【芝麻授权回调】调用芝麻评分或者调用信贷系统出错,sid:{},errMsg:{}", accreditCallbackDto.getSid(), e.getMessage());
                }
            }
        } catch (Exception e) {
            logger.error("【芝麻授权回调】出错,sid:{},errMsg:{}", accreditCallbackDto.getSid(), e.getMessage());
            resultDto = resultDto.server_error(resultDto, accreditCallbackDto.getSid());
            return response.fail(SystemErrorCodeEnum.JSS_CALL_EXTSYSTEM_ERROR, resultDto);
        }
        logger.info("【芝麻授权回调】结束!返回信息{}", JSON.toJSON(resultDto));
        return response.success(resultDto);
    }

    /**
     * 芝麻数据反馈
     *
     * @param zmDataFeedbackDto
     * @return
     */
//    @ApiMapping("Zhima.sendDataFeedback")
    public Response<String> sendDataFeedback(ZmDataFeedbackDto zmDataFeedbackDto) {
        Response response = new Response();
        try {
            Map<String, Object> map = zmDataFeedbackClient.getZmDataFeedbackResponse(zmDataFeedbackDto);
            /*try {
            //TODO:存储反馈结果
             if (isSuccess) {
                    ZmFeedback zmFeedback = convert2ZmFeedback(zmDataFeedbackDto);
                    zhimaFeedbackMapper.insert(zmFeedback);
                    List<ZmFeedbackData> list = convert2ZmFeedbackData(zmDataFeedbackDto, zmFeedback.getId());
                    zhimaFeedbackDataMapper.insertBatch(list);
                }
            } catch (Exception e) {
                logger.error("【芝麻数据反馈】芝麻数据反馈数据保存失败.{}", e);
            }*/
            return response.success(map);
        } catch (Exception e) {
            logger.error("【芝麻数据反馈】芝麻数据反馈接口出错.errMsg:{}", e);
            return response.fail(SystemErrorCodeEnum.JSS_CALL_EXTSYSTEM_ERROR);
        }

    }


    /**
     * 功能描述
     *
     * @param dto
     * @return
     */
    private boolean checkQueryParam(AccreditDto dto) {
        if (Strings.isNullOrEmpty(dto.getBusinessId())
                || Strings.isNullOrEmpty(dto.getName())
                || Strings.isNullOrEmpty(dto.getIdCard())
                || Strings.isNullOrEmpty(dto.getSid())) {
            return true;
        }
        return false;
    }

}
